package com.yanqu.road.server.manger.palace;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.decoration.DecorationSimple;
import com.yanqu.road.entity.estatewar.palace.PalaceFloorConfig;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eMailType;
import com.yanqu.road.entity.estatewar.UserEstateWarData;
import com.yanqu.road.entity.estatewar.palace.PalaceBattleRecord;
import com.yanqu.road.entity.estatewar.palace.PalaceRewardTime;
import com.yanqu.road.entity.estatewar.palace.UserPalaceData;
import com.yanqu.road.entity.log.LogPalaceDailyReward;
import com.yanqu.road.entity.log.LogPalacePos;
import com.yanqu.road.logic.bussiness.palace.PalaceBussiness;
import com.yanqu.road.logic.bussiness.player.UserEstateWarBussiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.DecorationPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.decoration.DecorationProto;
import com.yanqu.road.pb.estatewar.EstateWarProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.assistant.AssistantModule;
import com.yanqu.road.server.gameplayer.module.palace.PalaceModule;
import com.yanqu.road.server.gameplayer.module.player.DecorationModule;
import com.yanqu.road.server.gameplayer.module.player.EstateWarModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.EstateWarMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.TimeHelper;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
==============================================
 *皇宫逻辑类
==============================================
* 作者：zrq
* 时间：2022/1/27
**/
public class PalaceActivity {
    private Logger logger = LogManager.getLogger(this.getClass().getName());
    private RandomHelper randomHelper = new RandomHelper();
    private ActivityInfo activityInfo;                              //活动信息
    private Map<Integer, PalaceFloorConfig> palaceFloorConfigMap;          //皇宫位置信息
    private Map<Long, UserPalaceData> userPalaceDataMap;
    private Map<Long, PalaceRewardTime> palaceRewardTimeMap;
    private Map<Long, BigInteger> needUploadUserAbilityMap = new ConcurrentHashMap<>();

    private int PALACE_DAILY_REWARD_ITEM_ID;
    private int PALACE_LEVEL_LIMIT;
    private List<Integer> PALACE_WORSHIP_REWARD_PARAM_LIST = new ArrayList<>();
    private int PALACE_SHOW_NUM;
    private List<Integer> PALACE_TITLE_ADDITION_LIST = new ArrayList<>();
    private int PALACE_ACCOUNT_TIME;

    public int getPALACE_DAILY_REWARD_ITEM_ID() {
        return PALACE_DAILY_REWARD_ITEM_ID;
    }

    public int getPALACE_LEVEL_LIMIT() {
        return PALACE_LEVEL_LIMIT;
    }

    public List<Integer> getPALACE_WORSHIP_REWARD_PARAM_LIST() {
        return PALACE_WORSHIP_REWARD_PARAM_LIST;
    }

    public int getPALACE_SHOW_NUM() {
        return PALACE_SHOW_NUM;
    }

    public List<Integer> getPALACE_TITLE_ADDITION_LIST() {
        return PALACE_TITLE_ADDITION_LIST;
    }

    public int getPALACE_ACCOUNT_TIME() {
        return PALACE_ACCOUNT_TIME;
    }

    public PalaceActivity(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    public List<PalaceFloorConfig> getPalaceFloorConfigList() {
        return new ArrayList<>(palaceFloorConfigMap.values());
    }

    public PalaceFloorConfig getPalaceFloorConfig(int pos){
        return palaceFloorConfigMap.get(pos);
    }

    public boolean init(){
        userPalaceDataMap = PalaceBussiness.getUserPalaceDataMap(activityInfo.getActivityId());
        palaceRewardTimeMap = PalaceBussiness.getPalaceRewardTimeMap(activityInfo.getActivityId());
        reloadActivity(activityInfo);
        return true;
    }

    public boolean save(){
        for(UserPalaceData data : userPalaceDataMap.values()){
            if(data.isInsertOption()){
                PalaceBussiness.addUserPalaceData(data);
            }else if(data.isUpdateOption()){
                PalaceBussiness.updateUserPalaceData(data);
            }
        }
        for(PalaceRewardTime data : palaceRewardTimeMap.values()){
            if(data.isInsertOption()){
                PalaceBussiness.addPalaceRewardTime(data);
            }
        }
        return true;
    }

    /**
    * 描述：重载活动
    * 作者：zrq
    * 时间：2022/1/27
    * 参数：
    活动
    * 返回值：是否成功
    **/
    public boolean reloadActivity(ActivityInfo activityInfo){
        palaceFloorConfigMap = ActivityBussiness.getPalaceFloorConfigMap(activityInfo.getActivityId());
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(activityInfo.getActivityId());
        if(null != activityConfigMap) {
            PALACE_SHOW_NUM = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_SHOW_NUM);
            PALACE_DAILY_REWARD_ITEM_ID = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_DAILY_REWARD_ITEM_ID);
            PALACE_TITLE_ADDITION_LIST = ActivityHelper.getActivityConfigIntListValue(activityConfigMap, eActivityConfigType.PALACE_TITLE_ADD, "\\|");
            PALACE_LEVEL_LIMIT = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_LEVEL_LIMIT);
            PALACE_WORSHIP_REWARD_PARAM_LIST = ActivityHelper.getActivityConfigIntListValue(activityConfigMap, eActivityConfigType.PALACE_WORSHIP_REWARD_PARAM, "\\|");
            PALACE_ACCOUNT_TIME = ActivityHelper.getActivityConfigIntValue(activityConfigMap, eActivityConfigType.PALACE_ACCOUNT_TIME);
        }
        this.activityInfo = activityInfo;
        return true;
    }

    public int getPalaceActivityId(){
        if(null != activityInfo){
            return activityInfo.getActivityId();
        }
        return 0;
    }

    public boolean isPalaceActivityInTime(){
        return ActivityMgr.activityInShowTime(activityInfo);
    }

    public UserPalaceData getUserPalaceData(long userId){
        return userPalaceDataMap.get(userId);
    }

    public UserPalaceData initUserPalaceData(GamePlayer player){
        UserPalaceData userPalaceData = new UserPalaceData();
        userPalaceData.setActivityId(activityInfo.getActivityId());
        userPalaceData.setUserId(player.getUserId());
        userPalaceData.setPos(0);
        userPalaceData.setOnlyUnionMemberJoin(false);
        userPalaceData.setWorshipTime(0);
        userPalaceData.setInsertOption();
        synchronized (userPalaceDataMap){
            if(!userPalaceDataMap.containsKey(player.getUserId())){
                userPalaceDataMap.put(userPalaceData.getUserId(), userPalaceData);
            }
        }
        return userPalaceDataMap.get(player.getUserId());
    }

    public void syncPalaceUserData(GamePlayer player){
        EstateWarProto.PalaceUserDataSyncReqMsg.Builder crossMsg = EstateWarProto.PalaceUserDataSyncReqMsg.newBuilder();
        crossMsg.setActivityId(getPalaceActivityId());
        crossMsg.setUserId(player.getUserId());
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_PALACE_USER_DATA_SYNC, crossMsg);
        GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);
    }

    public void syncCrossPalaceUserData(EstateWarProto.PalaceUserDataSyncRespMsg respMsg){
        UserPalaceData userPalaceData = getUserPalaceData(respMsg.getUserId());
        if(null != userPalaceData){
            userPalaceData.setPos(respMsg.getPos());
            userPalaceData.setOnlyUnionMemberJoin(respMsg.getOnlyUnionMemberJoin());
            userPalaceData.setUnderAide(respMsg.getUnderAide());
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(respMsg.getUserId());
            if(null != player){
                if(userPalaceData.getPos() > 0) {
                    PalaceFloorConfig palaceFloorConfig = getPalaceFloorConfig(userPalaceData.getPos());
                    if (null != palaceFloorConfig) {
                        int estateSkinId = palaceFloorConfig.getSkinsReward();
                        EstateWarModule estateWarModule = player.getModule(EstateWarModule.class);
                        estateWarModule.unlockEstateSkin(estateSkinId);
                    }
                }
                player.getModule(PalaceModule.class).syncUserData();
            }
        }
    }

    public void getPalaceAideJoinApplyList(GamePlayer player){
        EstateWarProto.PalaceAideJoinApplyListReqMsg.Builder crossMsg = EstateWarProto.PalaceAideJoinApplyListReqMsg.newBuilder();
        crossMsg.setActivityId(getPalaceActivityId());
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_PALACE_AIDE_JOIN_APPLY_LIST, crossMsg);
        GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);
    }

    public void addBattleRecord(EstateWarProto.PalaceBattleRecordNotifyMsg notifyMsg){
        if(getPalaceActivityId() != notifyMsg.getActivityId()){
            return;
        }
        PalaceBattleRecord palaceBattleRecord = new PalaceBattleRecord();
        palaceBattleRecord.setActivityId(notifyMsg.getActivityId());
        palaceBattleRecord.setUserId(notifyMsg.getUserId());
        palaceBattleRecord.setRecordUid(UUIDHelper.randomUUID(GameServer.getInstance().getServerId() + ""));
        palaceBattleRecord.setWin(notifyMsg.getIsWin());
        palaceBattleRecord.setEnemyUserId(notifyMsg.getEnemyUserId());
        palaceBattleRecord.setEnemyUserInfo(PlayerBasePb.parseBaseUserInfo(notifyMsg.getEnemyUserInfo()));
        palaceBattleRecord.setOldPos(notifyMsg.getOldPos());
        palaceBattleRecord.setNowPos(notifyMsg.getNowPos());
        palaceBattleRecord.setRecordTime(System.currentTimeMillis());
        palaceBattleRecord.setInsertOption();
        UserPalaceData userPalaceData = getUserPalaceData(notifyMsg.getUserId());
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(notifyMsg.getUserId());
        if(notifyMsg.getIsWin()){//被打下来
            userPalaceData.setPos(notifyMsg.getNowPos());
            AutoLogMgr.add(new LogPalacePos(getPalaceActivityId(), notifyMsg.getUserId(), notifyMsg.getNowPos()));
            if(null != player){
                player.getModule(PalaceModule.class).syncUserData();
            }
            //发送位置变更邮件
            sendPalaceChangeMail(notifyMsg, palaceBattleRecord);

            //检测一下小玉助手
            if(null != player){
                checkAssistantMall(player, notifyMsg.getOldPos(), notifyMsg.getNowPos());
            }

            //检测一下皇城皮肤
            UserEstateWarData userEstateWarData = EstateWarMgr.getUserEstateWarData(notifyMsg.getUserId());
            boolean isChange = EstateWarMgr.checkEstatePalaceSkin(userEstateWarData);
            if(isChange) {
                if (null != player) {
                    player.getModule(EstateWarModule.class).syncUserEstateWarData();
                } else {
                    UserEstateWarBussiness.updateUserEstateWarData(userEstateWarData);
                }
            }
        }
        if(null != player){
            player.getModule(PalaceModule.class).addBattleRecord(palaceBattleRecord);
        }else {
            PalaceBussiness.addPalaceBattleRecord(palaceBattleRecord);
        }
    }

    private void checkAssistantMall(GamePlayer player, int oldPos, int nowPos){
        int oldTitleType = getTitleType(oldPos);
        int nowTitleType = getTitleType(nowPos);
        if(oldTitleType != nowTitleType){
            if(null != player){
                AssistantModule assistantModule = player.getModule(AssistantModule.class);
                boolean isChange = assistantModule.checkPalaceMall();
                if(isChange){
                    assistantModule.syncAssistantShopSet();
                }
            }
        }
    }

    private void sendPalaceChangeMail(EstateWarProto.PalaceBattleRecordNotifyMsg notifyMsg, PalaceBattleRecord palaceBattleRecord){
        //发送邮件通知位置变更
        String title;
        String content;
        String language = UserMgr.getLanguage(notifyMsg.getUserId());
        if(notifyMsg.getNowPos() <= 0){//驱逐
            title = MultipleLanguageMgr.getContent(MailManager.PALACE_POS_EXPEL_TITLE, language);
            content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.PALACE_POS_EXPEL_CONTENT, language),
                    ServerListMgr.getServerName(palaceBattleRecord.getEnemyUserInfo().getServerId(), language),
                    palaceBattleRecord.getEnemyUserInfo().getNickName(),
                    getFullTitleTypeName(notifyMsg.getOldPos(), language));
        }else {//变更
            title = MultipleLanguageMgr.getContent(MailManager.PALACE_POS_CHANGE_TITLE, language);
            content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.PALACE_POS_CHANGE_CONTENT, language),
                    ServerListMgr.getServerName(palaceBattleRecord.getEnemyUserInfo().getServerId(), UserMgr.getLanguage(notifyMsg.getUserId())),
                    palaceBattleRecord.getEnemyUserInfo().getNickName(),
                    getFullTitleTypeName(notifyMsg.getOldPos(), language),
                    getFullTitleTypeName(notifyMsg.getNowPos(), language));
        }
        MailManager.sendMail(notifyMsg.getUserId(), eMailType.SYSTEM.getValue(), "", content, title);
    }

    public Property getWorshipReward(){
        int param1 = 0;
        int param2 = 0;
        if(PALACE_WORSHIP_REWARD_PARAM_LIST.size() >= 2){
            param1 = PALACE_WORSHIP_REWARD_PARAM_LIST.get(0);
            param2 = PALACE_WORSHIP_REWARD_PARAM_LIST.get(1);
        }
        int randomValue = randomHelper.next(param1, param2 + 1);
        Property reward = new Property(PALACE_DAILY_REWARD_ITEM_ID, BigInteger.valueOf(randomValue));
        return reward;
    }

    public synchronized void dailyTask(){
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();
        PalaceRewardTime palaceRewardTime = palaceRewardTimeMap.get(zeroTime);
        if(null != palaceRewardTime){//已经发过奖了
            return;
        }
        long nowTimeSeconds = TimeHelper.getSysTimeSeconds();
        if(nowTimeSeconds < getPALACE_ACCOUNT_TIME() * 60){//还么到结算时间
            return;
        }

        for(UserPalaceData data : userPalaceDataMap.values()){
            try {
                Property palaceReward = new Property();
                if (data.getPos() > 0) {
                    PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(data.getPos());
                    palaceReward.addProperty(PropertyHelper.parseStringToProperty(palaceFloorConfig.getDailyReward()));
                }
                String rewardStr = PropertyHelper.parsePropertyToString(palaceReward);
                if (!StringUtils.isNullOrEmpty(rewardStr)) {
                    String language = UserMgr.getLanguage(data.getUserId());
                    String title = MultipleLanguageMgr.getContent(MailManager.PALACE_POS_REWARD_TITLE, language);
                    String content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.PALACE_POS_REWARD_CONTENT, language),
                            getTitleTypeName(data.getPos(), language));
                    MailManager.sendMail(data.getUserId(), eMailType.DAILY.getValue(), rewardStr, content, title);
                    AutoLogMgr.add(new LogPalaceDailyReward(getPalaceActivityId(), data.getUserId(), 0, data.getPos(), rewardStr));
                }
                Property aideReward = new Property();
                if (data.getUnderAide() > 0) {
                    PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(data.getUnderAide());
                    aideReward.addProperty(PropertyHelper.parseStringToProperty(palaceFloorConfig.getRecruitReward()));
                }
                rewardStr = PropertyHelper.parsePropertyToString(aideReward);
                if (!StringUtils.isNullOrEmpty(rewardStr)) {
                    String language = UserMgr.getLanguage(data.getUserId());
                    String title = MultipleLanguageMgr.getContent(MailManager.PALACE_AIDE_REWARD_TITLE, language);
                    String content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.PALACE_AIDE_REWARD_CONTENT, language),
                            getTitleTypeName(data.getUnderAide(), language),
                            getTitleTypeName(data.getUnderAide(), language));
                    MailManager.sendMail(data.getUserId(), eMailType.DAILY.getValue(), rewardStr, content, title);
                    AutoLogMgr.add(new LogPalaceDailyReward(getPalaceActivityId(), data.getUserId(), 1, data.getUnderAide(), rewardStr));
                }
            }catch (Exception e){
                logger.error("send daily reward error,userId:{},pos:{}", data.getUserId(),data.getPos(), e);
            }
        }
        palaceRewardTime = new PalaceRewardTime();
        palaceRewardTime.setActivityId(getPalaceActivityId());
        palaceRewardTime.setRewardTime(zeroTime);
        palaceRewardTime.setInsertOption();
        palaceRewardTimeMap.put(palaceRewardTime.getRewardTime(), palaceRewardTime);
    }

    public void syncDecorationSimple(GamePlayer player){
        List<DecorationSimple> dataList = player.getModule(DecorationModule.class).getHonoraryTitleDecorationSimpleList();
        if(dataList.size() > 0){
            EstateWarProto.PalaceDecorationSimpleSyncMsg.Builder syncMsg = EstateWarProto.PalaceDecorationSimpleSyncMsg.newBuilder();
            syncMsg.setActivityId(getPalaceActivityId());
            syncMsg.setUserId(player.getUserId());
            for(DecorationSimple data : dataList){
                DecorationProto.DecorationSimpleTempMsg.Builder msg = DecorationPb.parseDecorationSimpleTempMsg(data);
                if(null != msg){
                    syncMsg.addDataList(msg);
                }
            }
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_PALACE_PLAYER_DECORATION_SYNC, syncMsg);
            GamePlayerMgr.sendPacket(0, pbMsg);
        }
    }

    public int getTitleType(int pos){
        int titleType = 0;
        if(pos > 0){
            PalaceFloorConfig palaceFloorConfig = palaceFloorConfigMap.get(pos);
            if(null != palaceFloorConfig){
                titleType = palaceFloorConfig.getTitleType();
            }
        }
        return titleType;
    }

    public String getTitleTypeName(int pos, String language){
        String name = "";
        int titleType = getTitleType(pos);
        if(titleType > 0){
            name = MultipleLanguageMgr.getContent("PALACE_TITLE_NAME_" + titleType, language);
        }
        return name;
    }

    public String getFullTitleTypeName(int pos, String language){
        String name = getTitleTypeName(pos, language);
        if(!StringUtils.isNullOrEmpty(name)){
            name = name + pos;
        }
        return name;
    }

    public void syncUserAbility(long userId, BigInteger ability){
        UserPalaceData userPalaceData = getUserPalaceData(userId);
        if(null != userPalaceData){//有玩家信息再上传
            synchronized (needUploadUserAbilityMap){
                needUploadUserAbilityMap.put(userId, ability);
            }
        }
    }

    public void uploadUserAbility(){
        synchronized (needUploadUserAbilityMap){
            if(needUploadUserAbilityMap.size() > 0) {
                EstateWarProto.PalacePlayerAbilitySyncMsg.Builder syncMsg = EstateWarProto.PalacePlayerAbilitySyncMsg.newBuilder();
                syncMsg.setActivityId(getPalaceActivityId());
                for (Map.Entry<Long, BigInteger> entryData : needUploadUserAbilityMap.entrySet()) {
                    EstateWarProto.PalacePlayerAbilityTempMsg.Builder msg = EstateWarProto.PalacePlayerAbilityTempMsg.newBuilder();
                    msg.setUserId(entryData.getKey());
                    msg.setAbility(entryData.getValue().toString());
                    syncMsg.addDataList(msg);
                }
                YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_PALACE_PLAYER_ABILITY_SYNC, syncMsg);
                GamePlayerMgr.sendPacket(0, pbMsg);
                needUploadUserAbilityMap.clear();
            }
        }
    }

    public void clearPalaceAideSetting(long userId){
        UserPalaceData userPalaceData = getUserPalaceData(userId);
        if(null != userPalaceData && userPalaceData.isOnlyUnionMemberJoin()){
            PalaceActivityMgr.sendPalaceAideSetting(getPalaceActivityId(), userId, false, false);
        }
    }
}
